package com.alibaba.cirtus.ots.application.adapter.ability.facade.serviceV2.sap;

import com.alibaba.cirtus.ots.application.adapter.ability.model.sdo.AllocateApplyOrderDetailCreateSDO;
import com.alibaba.cirtus.ots.application.adapter.ability.model.sdo.AllocateApplyOrderUpdateSDO;
import com.alibaba.cirtus.ots.application.adapter.ability.utils.InfoUtil;
import com.alibaba.cirtus.ots.application.adapter.ability.utils.RequestUtils;
import com.alibaba.citrus.ots.common.annotation.ProcessInvoker;
import com.alibaba.citrus.ots.common.util.SapAndCrmFieldDealUtils;
import com.alibaba.cz.base.tool.FeatureUtil;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.mninventorycenter.model.dto.DictionaryQueryRequest;
import com.epoch.app.mninventorycenter.model.dto.DictionaryResponse;
import com.epoch.app.mninventorycenter.model.dto.QueryDictionaryListApiRequest;
import com.epoch.app.mninventorycenter.service.MnInventoryCenterService;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapIf005Request;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapIf005SDO;
import com.epoch.app.otsapplicationadaptersdk.sap.MnSapIf005detail;
import com.epoch.app.otsapplicationadaptersdk.sapv2.mnsapif005v2.dto.DoHandlerRequest;
import com.epoch.app.otsapplicationadaptersdk.sapv2.mnsapif005v2.service.MnSapIf005V2Service;
import com.epoch.app.otsapplicationadaptersdk.service.ApiAdapterService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author hanguo
 * @Description 平台请求sap预报单创建
 * @date 2021/9/26
 */
@Component
@Primary
public class MnSapIf005V2ServiceImpl implements MnSapIf005V2Service {
    private final Log log = Log.getLogger(MnSapIf005V2ServiceImpl.class);

    private final static Integer TYPE = 2;

    @Resource
    private ApiAdapterService apiAdapterService;
    @Resource
    private MnInventoryCenterService mnInventoryCenterService;

    private static final String PLAN_SUGGEST_QUANTITY= "planSuggestQuantity";
    private static final String ALGORITHM_SUGGEST_QUANTITY ="algorithmSuggestQuantity";
    private static final String APPLY_DEVIATION_REASON = "applyDeviationReason";

    @Override
    @ProcessInvoker(remark = "MnSapIf005V2Service", errorCode = "OTS-02-007-00-16-999", printLog = true)
    public Object doHandler(DoHandlerRequest doHandlerRequest) {
        log.info("MnSapIf005ServiceImpl_doHandler_request:{}",JSON.toJSONString(doHandlerRequest));
        AllocateApplyOrderUpdateSDO allocateApplyOrderUpdateSDO = JSON.parseObject(doHandlerRequest.getMessage(), AllocateApplyOrderUpdateSDO.class);
        MnSapIf005Request request = new MnSapIf005Request();
        request.setMessageHeader(RequestUtils.generateMessageHeader("MnSapIf005","ECC"));
        MnSapIf005SDO sdo = new MnSapIf005SDO();
        //报价单类型
        sdo.setOrderType("ZQT");
        //预报单id
        sdo.setOtsPreOrderId(allocateApplyOrderUpdateSDO.getCode());
        //销售组织 总部组织
        sdo.setSaleOrganizationCode(allocateApplyOrderUpdateSDO.getHeadquartersOrganizationCode());
        //分销渠道 90调拨 20销售 除了总部销售都是90
        sdo.setChannelCode(allocateApplyOrderUpdateSDO.getHeadquartersChannelCode());
        //部门 产品组
        sdo.setProductGroup(null == allocateApplyOrderUpdateSDO.getGoodsGroup()?"":allocateApplyOrderUpdateSDO.getGoodsGroup().toString());
        //计划类型选总部
        if(Objects.nonNull(allocateApplyOrderUpdateSDO.getType())&&TYPE==allocateApplyOrderUpdateSDO.getType()){
            //判断是不是工厂直发，如果是取地址code和客户编码
            //F-b的场景SAP005接口；
            //取预报单上所选择的客户编码和客户地址编码，作为接口中的soldPartCode，deliveryPartCode；channelCode=20；
            if (allocateApplyOrderUpdateSDO.getIsDTC()){
                //售达方 收货仓库
                sdo.setSoldPartCode(allocateApplyOrderUpdateSDO.getCustomer());
                //送达方
                sdo.setDeliveryPartCode(allocateApplyOrderUpdateSDO.getCustomerAddress());
            }else {
                //F- B、F1-B  的场景 取收货逻辑仓库锁配置的售达方编码和送达方编码，作为接口中soldPartCode，deliveryPartCode；channelCode=20；
                //售达方 收货仓库
//                sdo.setSoldPartCode(allocateApplyOrderUpdateSDO.getSapSalesBPCode());
                sdo.setSoldPartCode(InfoUtil.getFirstCode(allocateApplyOrderUpdateSDO.getSapSalesBPCode()));
                //送达方
//                sdo.setDeliveryPartCode(allocateApplyOrderUpdateSDO.getSapDeliveryBPCode());
                sdo.setDeliveryPartCode(InfoUtil.getFirstCode(allocateApplyOrderUpdateSDO.getSapDeliveryBPCode()));
            }
            sdo.setChannelCode("20");
        }else{
            //F-F1 的场景 取收货逻辑仓库所配置的售达方编码和送达方编码，作为接口中soldPartCode，deliveryPartCode；channelCode=20；

            //售达方 收货仓库
            sdo.setSoldPartCode(allocateApplyOrderUpdateSDO.getSapInternalSalesBPCode());
            //送达方
            sdo.setDeliveryPartCode(allocateApplyOrderUpdateSDO.getSapInternalDeliveryBPCode());
            sdo.setChannelCode("90");
        }
        //备注
        sdo.setRemark(allocateApplyOrderUpdateSDO.getRemark());
        //交货工厂 发货仓工厂code
        sdo.setDeliveryFactoryCode(allocateApplyOrderUpdateSDO.getDeliveryFactoryCode());
        //库存地点 发货仓的库存地点code
        sdo.setDeliveryInventoryCode(allocateApplyOrderUpdateSDO.getDeliveryInventoryCode());
        //有效起始日期 默认 前端取
        sdo.setBeginTime(null == allocateApplyOrderUpdateSDO.getTakeEffectTime()?"":getDateString(allocateApplyOrderUpdateSDO.getTakeEffectTime()));
        //报价有效至 前端新加
        sdo.setEndTime(null == allocateApplyOrderUpdateSDO.getInvalidDate()?"":getDateString(allocateApplyOrderUpdateSDO.getInvalidDate()));
        //交货日期 期望交货日期
        sdo.setExceptedDeliveryTime(null == allocateApplyOrderUpdateSDO.getHopeDeliveryTime()?"":getDateString(allocateApplyOrderUpdateSDO.getHopeDeliveryTime()));
        //创建时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdo.setCreateTime(null == allocateApplyOrderUpdateSDO.getGmtCreate()?"":sdf.format(allocateApplyOrderUpdateSDO.getGmtCreate()));
        //创建人
        sdo.setCreator(StringUtils.isNotBlank(allocateApplyOrderUpdateSDO.getCreatorName()) ? allocateApplyOrderUpdateSDO.getCreatorName() :
                allocateApplyOrderUpdateSDO.getCreator());
        //是否还货 默认否
        sdo.setReturnGood(null == allocateApplyOrderUpdateSDO.getReturnGood()?"0":allocateApplyOrderUpdateSDO.getReturnGood().toString());
        //调拨预报单类型
        sdo.setType(null == allocateApplyOrderUpdateSDO.getType()?"":allocateApplyOrderUpdateSDO.getType().toString());
        //扩展信息
        sdo.setFeatures("");
        //预留字段
//        sdo.setExt("");
        //09.19 运输方式
        sdo.setExt(allocateApplyOrderUpdateSDO.getShipMethod());
        //添加明细对象
        List<MnSapIf005detail> mnSapIf005details = new ArrayList<>();
        //判断下是否需要查询字典服务
        boolean needQueryDictionary = Nullable.stream(allocateApplyOrderUpdateSDO.getList()).map(AllocateApplyOrderDetailCreateSDO::getFeatures)
                .filter(StringUtils::isNotBlank).map(FeatureUtil::fromString).filter(MapUtils::isNotEmpty)
                .anyMatch(map -> map.containsKey(APPLY_DEVIATION_REASON));
        Map<String,String> dictionaryMap = Maps.newHashMap();
        if (needQueryDictionary){
            DictionaryQueryRequest dictionaryQueryRequest = new DictionaryQueryRequest();
            dictionaryQueryRequest.setGroup(APPLY_DEVIATION_REASON);
            Result<List<DictionaryResponse>> queryDictionaryDataListApi = mnInventoryCenterService.queryDictionaryDataListApi(dictionaryQueryRequest);
            if (queryDictionaryDataListApi != null && CollectionUtils.isNotEmpty(queryDictionaryDataListApi.getResult())){
                queryDictionaryDataListApi.getResult().forEach(dictionaryResponse -> {
                    dictionaryMap.put(dictionaryResponse.getCode(),dictionaryResponse.getName());
                    dictionaryMap.put(InfoUtil.deleteZeroPrefix(dictionaryResponse.getCode()),dictionaryResponse.getName());
                });
            }
        }
        for (AllocateApplyOrderDetailCreateSDO allocateApplyOrderDetailCreateSDO:allocateApplyOrderUpdateSDO.getList()){
            MnSapIf005detail mnSapIf005detail = new MnSapIf005detail();
            //物料行id 行号
            mnSapIf005detail.setAllocateApplyOrderLineId(null == allocateApplyOrderDetailCreateSDO.getLineNo()?null:allocateApplyOrderDetailCreateSDO.getLineNo().toString());
            //物料编号 货品编码
            mnSapIf005detail.setScItemId(SapAndCrmFieldDealUtils.generateIdField(allocateApplyOrderDetailCreateSDO.getScItemId()));
            //数量
            mnSapIf005detail.setQuantity(allocateApplyOrderDetailCreateSDO.getApplyQuantity());
            //销售单位      基本单位		货品接口找
            mnSapIf005detail.setSaleUnit(allocateApplyOrderDetailCreateSDO.getUom());
            //行备注
            mnSapIf005detail.setRemarks(allocateApplyOrderDetailCreateSDO.getRemark());
            //扩展信息
            mnSapIf005detail.setFeatures("");
            //预留字段
            mnSapIf005detail.setExt("");
            Map<String, String> featuresMap = FeatureUtil.fromString(allocateApplyOrderDetailCreateSDO.getFeatures());
            if (MapUtils.isNotEmpty(featuresMap)){
                //计划建议量
                mnSapIf005detail.setExt(featuresMap.get(PLAN_SUGGEST_QUANTITY));
                //算法建议量
                mnSapIf005detail.setExt1(featuresMap.get(ALGORITHM_SUGGEST_QUANTITY));
                //提报偏差原因
                mnSapIf005detail.setExt2(dictionaryMap.get(featuresMap.get(APPLY_DEVIATION_REASON)));
            }

            mnSapIf005details.add(mnSapIf005detail);
        }
        sdo.setItems(mnSapIf005details);
        request.setData(Lists.newArrayList(sdo));
        log.info("MnSapIf005ServiceImpl_doHandler_result:{}",JSON.toJSONString(request));
        return apiAdapterService.reqSapForecastOrderCreate(request);
    }

    private String getDateString(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }
}
